package com.weavernorth.retailExperienceAward.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weavernorth.retailExperienceAward.dto.sapMessEntity;
import com.weavernorth.util.Logger4jUtil;
import net.sf.json.xml.XMLSerializer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import sun.misc.BASE64Encoder;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Author: bruseewang
 * @Package: com.weavernorth.action.jb.utils
 * @date: 2020/5/15 9:42
 * @description:
 */
public class sendDataToSapUtils {
//    private static Log log = LogFactory.getLog(sendDataToSapUtils.class);
//    private static Logger log = Logger4jUtil.getLoggerByName("/action/Utils/sendDataToSapUtils/");
    /**
     * 推送SAP,判断是否锁定
     *
     * @param strGzfw SAP工资范围
     * @param strSxrq 生效日期
     * @return
     */
    public static String judgeLock(Logger log,String strGzfw, String strSxrq) {
        //返回值
        String strMessage = "";
        //基础类
        BaseBean bb = new BaseBean();
        //返回标识
        String testType = "";
        //拼接xml
        StringBuffer requestXml = new StringBuffer();
        requestXml.append("<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:urn='urn:sap-com:document:sap:rfc:functions'>");
        requestXml.append("<soapenv:Header/>");
        requestXml.append("<soapenv:Body>");
        requestXml.append("<urn:ZHRI_080>");
        requestXml.append("<IV_ABKRS>" + strGzfw + "</IV_ABKRS>");
        requestXml.append("<IV_BEGDA>" + strSxrq + "</IV_BEGDA>");
        requestXml.append("<RETURN>");
        requestXml.append("<item>");
        requestXml.append("<TYPE></TYPE>");
        requestXml.append("<ID></ID>");
        requestXml.append("<NUMBER></NUMBER>");
        requestXml.append("<MESSAGE></MESSAGE>");
        requestXml.append("<LOG_NO></LOG_NO>");
        requestXml.append("<LOG_MSG_NO></LOG_MSG_NO>");
        requestXml.append("<MESSAGE_V1></MESSAGE_V1>");
        requestXml.append("<MESSAGE_V2></MESSAGE_V2>");
        requestXml.append("<MESSAGE_V3></MESSAGE_V3>");
        requestXml.append("<MESSAGE_V4></MESSAGE_V4>");
        requestXml.append("<PARAMETER></PARAMETER>");
        requestXml.append("<ROW></ROW>");
        requestXml.append("<FIELD></FIELD>");
        requestXml.append("<SYSTEM></SYSTEM>");
        requestXml.append("</item>");
        requestXml.append("</RETURN>");
        requestXml.append("</urn:ZHRI_080>");
        requestXml.append("</soapenv:Body>");
        requestXml.append("</soapenv:Envelope>");
        log.info("判断工资范围是否锁定,推送xml:" + requestXml);
        String strGzfwUrl = Util.null2String(bb.getPropValue("personnel-erdos", "gzfwurl"));
        log.info("工资范围推送路径:" + strGzfwUrl);
        try {
            String strReturnMessage = sendPost(log,strGzfwUrl, requestXml.toString(), "utf-8");
            //解析返回值:
            Document doc = null;

            doc = DocumentHelper.parseText(strReturnMessage.toString());
            Iterator<Element> its2 = doc.selectNodes("//TYPE").iterator();
            while (its2.hasNext()) {
                Element element = its2.next();
                testType = element.getText();
                if (!"".equals(testType)) {
                    bb.writeLog("testType值为:" + testType + "\n");
                    break;
                }

            }
            //返回值失败时,则提示失败
            if ("E".equals(testType)) {
                Iterator<Element> its3 = doc.selectNodes("//MESSAGE").iterator();
                while (its3.hasNext()) {
                    Element element2 = its3.next();
                    strMessage = element2.getText();
                    if (!"".equals(strMessage)) {
                        break;
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strMessage;
    }


    /**
     * 推送方法
     *
     * @param strUrl
     * @param strRequestXml
     * @param strEncoding
     * @return
     * @throws IOException
     */
    public static String sendPost(Logger log,String strUrl, String strRequestXml, String strEncoding) throws IOException {
        log.info("请求地址=" + strUrl);
        log.info("请求xml=" + strRequestXml);
        //基础类
        BaseBean bb = new BaseBean();

        String strBody = "";
        //创建httpclient对象
        CloseableHttpClient client = HttpClients.createDefault();

        //创建post方式请求对象
        try {
            HttpPost httpPost = new HttpPost(strUrl);

            //装填参数
            StringEntity stringEntity = new StringEntity(strRequestXml, "utf-8");
            //log.info("请求xml=" + strRequestXml);
            //设置参数到请求对象中
            httpPost.setEntity(stringEntity);
            //获取用户名
            String strUsername = Util.null2String(bb.getPropValue("personnel-erdos", "username"));
            //获取密码
            String strPassword = Util.null2String(bb.getPropValue("personnel-erdos", "password"));
            //sap的接口需验证
            String strValue = "Basic " + (new BASE64Encoder().encode((strUsername + ":" + strPassword).getBytes()));
            httpPost.setHeader("Authorization", strValue);
            httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");

            //执行请求操作，并拿到结果（同步阻塞）
            CloseableHttpResponse response = client.execute(httpPost);
            //获取结果实体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                //按指定编码转换结果实体为String类型
                strBody = EntityUtils.toString(entity, strEncoding);
                // log.info("返回结果=" + strBody);
            }
            EntityUtils.consume(entity);
            //释放链接
            response.close();
        } catch (Exception e) {
            log.info("异常捕获=" + e);
        }
        return strBody;
    }

    /**
     * 根据工资范围id得到工资范围bpm值
     *
     * @param strGzfwId
     * @return
     */
    public static String getGzfw(String strGzfwId) {
        RecordSet rs = new RecordSet();
        //返回值
        String strGzhsfw = "";
        String sql = "select gzhsfw from uf_gzfw where id = ?";
        rs.executeQuery(sql, strGzfwId);
        if (rs.next()) {
            strGzhsfw = Util.null2String(rs.getString("gzhsfw"));
        }
        return strGzhsfw;

    }


    /**
     * 根据人员id得到工资范围bpm值
     *
     * @param strUserid
     * @return
     */
    public static String getGzfwFromUser(String strUserid) {
        RecordSet rs = new RecordSet();
        //返回值
        String strGzhsfw = "";
        String sql = "select gzhsfw from uf_gzfw ug,cus_fielddata cf  where ug.id=cf.field23  and cf.id=? and cf.scopeid='1'";
        rs.executeQuery(sql, strUserid);
        if (rs.next()) {
            strGzhsfw = Util.null2String(rs.getString("gzhsfw"));
        }
        return strGzhsfw;

    }

    /**
     * 根据员工id得到员工编码
     *
     * @param strUserid 员工id
     * @return 员工编码
     */
    public static String getWorkcode(String strUserid) {
        String strWorkcode = "";
        RecordSet rs = new RecordSet();
        String strSql = "select workcode from hrmresource where id=?";
        rs.executeQuery(strSql, strUserid);
        if (rs.next()) {
            strWorkcode = Util.null2String(rs.getString("workcode"));
        }

        return strWorkcode;

    }

    /**
     * 根据员工编码得到员工id
     *
     * @param strWorkcode 员工编码
     * @return 员工编码
     */
    public static String getUserid(String strWorkcode) {
        String strUserid = "";
        RecordSet rs = new RecordSet();
        String strSql = "select id from hrmresource where workcode=?";
        rs.executeQuery(strSql, strWorkcode);
        if (rs.next()) {
            strUserid = Util.null2String(rs.getString("id"));
        }

        return strUserid;

    }

    public static String[] responseResult(String responseXml){
        String[] strResult=new String[2];
        try {
            Document doc=null;//引用dom4j组件
            doc = DocumentHelper.parseText(responseXml.toString());
            //selectNodes("Type")从当前节点的子节点中选择名为“Type”的节点
            //selectNodes("/Type")从根节点的子节点中选择名为“Type”的节点
            //selectNodes("//Type")从任意节点上选择名为“Type”的节点
            Iterator<Element> its2 = doc.selectNodes("//TYPE").iterator();
            int intType = 0;
            String resultCode=null;//接口返回状态码
            Boolean bolFlag=true;
            String strMessage="";
            while (its2.hasNext()){
                Element element = its2.next();
                resultCode=element.getText();
                if ("E".equals(resultCode)) {
                    bolFlag = false;
                    break;
                }
                intType++;
            }
            int intMess = 0;
            //返回值失败时,则提示失败
            if ("E".equals(resultCode)) {
                Iterator<Element> its3 = doc.selectNodes("//MESSAGE").iterator();
                while (its3.hasNext()) {
                    Element element2 = its3.next();
                    strMessage = element2.getText();
                    if (intMess == intType) {
                        if (!"".equals(strMessage)) {
                            bolFlag = false;
                            break;
                        }
                    }
                    intMess++;
                }
            }
            if (!bolFlag) {
                strResult[0]="f";
                strResult[1]=strMessage;
            } else {
                strResult[0]="s";
                strResult[1]="SUCCESS";
            }
        }catch (Exception e) {
            strResult[0]="e";
            strResult[1]=e.toString();
        }finally {
            return strResult;
        }
    }


    //查询节点是否存在
    public static Boolean eleisExists(String strXml,String strElement) {
        try {
            Document doc=null;//引用dom4j组件
            doc = DocumentHelper.parseText(strXml.toString());
            Integer count=0;
                    count= doc.selectNodes(strElement).size();
            if(count>0){
                return true;
            }
            else{
                return false;
            }
        }catch (Exception e){
            return false;
        }

    }


    /**
     * 传送SAP返回JSON对象
     *
     * @return
     */
    public static JSONObject toServices(Logger log,String requestXml) {

        BaseBean aa = new BaseBean();
        aa.writeLog("请求的requestXml：" + requestXml);
        //获取properties中接口地址值
        String strRealUrl = Util.null2String(aa.getPropValue("sapUrl", "sapZjk"));
        aa.writeLog("接口地址值：" + strRealUrl);
        //调用方法传入的参数
        String strEncoding = "UTF-8";
        String result = null;
        StringBuffer strTest = new StringBuffer();
        strTest.append("推送的所有明细表数据共有如下错误：（按错误个数排序）：");
        //区分是否全部是成功的
        String strFlag = "true";
        //sap返回的所有信息
        JSONArray jsonArray = new JSONArray();
        JSONArray jsonResult = new JSONArray();
        JSONObject returnResult=new JSONObject();
        try {
            result = sendPost(log,strRealUrl, requestXml, strEncoding);

            //解析result
            //返回的xml
            log.info("SAP响应的结果xml：" + result);
            //获取返回结果
            Document doc = null;
            try {
                doc = DocumentHelper.parseText(result.toString());
                //判断失败成功与否的字段
                Iterator<Element> its2 = doc.selectNodes("//TYPE").iterator();
                //错误信息
                Iterator<Element> its3 = doc.selectNodes("//MESSAGE").iterator();

                while (its2.hasNext()) {
                    //因为SAP返回两条错误消息,一条错误结果,一条错误原因,此处只取错误原因
                    //封存返回数据
                    JSONObject jsonObject = new JSONObject();
                    Element element = its2.next();
                    Element element3 = its3.next();
                    if (element3.getText().contains("数据写入失败")){
                        strFlag="false";
                    }
                    String strFlagSAP = element.getText();
                    String strMsg = element3.getText();
                    jsonObject.put("flag", strFlagSAP);
                    jsonObject.put("mess", strMsg);
                    jsonArray.add(jsonObject);

                }
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("result",strFlag);
                jsonResult.add(jsonObject);
                returnResult.put("res",jsonArray);
                returnResult.put("result",jsonResult);
            } catch (Exception e) {
                log.info("传送至SAP发生异常,异常信息为：" + e.toString());
                e.printStackTrace();
            }


        } catch (Exception e) {
            log.info("传送至SAP发生异常,异常信息为：" + e.toString());
            e.printStackTrace();
        }
        return returnResult;
    }

    /**
     * 传送SAP返回集合对象
     *List<sapMessEntity>
     * @return
     */
    public static List<sapMessEntity> toSapMethod(Logger log,String requestXml) {
        BaseBean aa = new BaseBean();
        log.info("请求的requestXml：" + requestXml);
        //获取properties中接口地址值
        String strRealUrl = Util.null2String(aa.getPropValue("sapUrl", "sapZjk"));
        log.info("接口地址值：" + strRealUrl);
        //调用方法传入的参数
        String strEncoding = "UTF-8";
        String result = null;
        String strBody="";
        String strResponse="";
        String strReturn="";
        String strAllFlag="true";//判断是否全部成功或全部失败
        List<sapMessEntity> list=new ArrayList<>();
        try {
            //1.发送请求
            result = sendPost(log,strRealUrl, requestXml, strEncoding);
            XMLSerializer xmlSerializer = new XMLSerializer();
            //2.解析xml数据
            String resutStr = xmlSerializer.read(result).toString();
            log.info("SAP接口返回信息："+resutStr);
            //3.xml数据转为JSON对象
            net.sf.json.JSONObject object = net.sf.json.JSONObject.fromObject(resutStr);
            //4.查询body节点
            strBody=object.getString("soap-env:Body");
            //5.将body节点下字符串转为Json对象
            net.sf.json.JSONObject objResponse =net.sf.json.JSONObject.fromObject(strBody);
            //6.获取body节点下的response节点
            for (Object o : objResponse.keySet()) {
                if (o.toString().toLowerCase().contains("response")){
                    strResponse=o.toString();
                }
            }
            //如：n0:ZHRI_075Response:获取response下的节点
            strReturn=objResponse.getString(strResponse);
            //7.获取接口返回的return标签下的信息
            net.sf.json.JSONArray resultMes = net.sf.json.JSONObject.fromObject(strReturn).getJSONArray("RETURN");
            log.info("接口返回数据解析为json："+resultMes);
            String strType=null;
            String strMessage=null;
            String strGh=null;
            //8.数据处理重构,返回list集合
            for (int i=1;i<resultMes.size();i++){
                sapMessEntity entity=new sapMessEntity();
                net.sf.json.JSONObject obj=resultMes.getJSONObject(i);
                strType=obj.getString("TYPE");
                strMessage=obj.getString("MESSAGE");
                if (strType!=null&&strMessage!=null){
                    if (strMessage.contains("[")&&strMessage.contains("]")) {
                        strGh = strMessage.substring(strMessage.indexOf('[') + 1, strMessage.indexOf(']'));
                        if ("S".equals(strType)) {
                            entity.setType(strType);
                            entity.setYgbh(strGh);
                            entity.setMessage(strMessage);
                        } else if ("E".equals(strType)) {
                            strAllFlag="false";
                            entity.setType(strType);
                            entity.setYgbh(strGh);
                            entity.setMessage(strMessage);

                        }
                    }else{
                        entity.setType(strType);
                        entity.setMessage(strMessage);
                        entity.setYgbh("");
                    }
                }
                if (entity!=null){
                    list.add(entity);
                }
            }
            log.info("list集合："+list.toString());
        } catch (Exception e) {
            sapMessEntity entity=new sapMessEntity();
            log.info("SAP接口传数异常,异常消息："+e.toString());
            strAllFlag="false";
            entity.setType("allE");
            entity.setMessage(e.toString());
            entity.setYgbh("");
            list.add(entity);
            e.printStackTrace();
        }
        if ("true".equals(strAllFlag)){
            sapMessEntity entity=new sapMessEntity();
            entity.setType("allS");
            entity.setMessage("成功！");
            entity.setYgbh("");
            list.add(entity);
        }
        return list;
    }

}
